<?php 

class BetsManager
{

	private $_db;
	
	public function __construct(PDO $db)
	{
		$this->setDb($db);
	}
	
	public function setDb($db)
	{
		$this->_db = $db;
	}
	
	public function add(Bets $bets)
	{
		//On teste le type de Bets
		switch(get_class($bets))
		{
			case "BetsBasket": //Si c'est un concours sur du basket : on ajoute un bets dans la table bets_basket
				$reqInsert = $this->_db->prepare("INSERT INTO bets_basket SET status = :status, user_id= :user_id, contest_id= :contest_id, scheduleEvent_id= :scheduleEvent_id, dateBet= :dateBet, winningTeam= :winningTeam, pointsDifference= :pointsDifference, pointsTotal= :pointsTotal, overtime= :overtime");
				$reqInsert->bindValue(":status", $bets->status());
				$reqInsert->bindValue(":user_id", $bets->user_id());
				$reqInsert->bindValue(":contest_id", $bets->contest_id());
				$reqInsert->bindValue(":scheduleEvent_id", $bets->scheduleEvent_id());
				$reqInsert->bindValue(":dateBet", $bets->dateBet());
				$reqInsert->bindValue(":winningTeam", $bets->winningTeam());
				$reqInsert->bindValue(":pointsDifference", $bets->pointsDifference());
				$reqInsert->bindValue(":pointsTotal", $bets->pointsTotal());
				$reqInsert->bindValue(":overtime", $bets->overtime());
				break;
			default: //Si c'est une classe qui n'est pas "connue" : on ne fait rien
				return;
		}
		$reqInsert->execute();
	}
	public function delete(Bets $bets)
	{
		//On teste le type de Bets
		switch(get_class($bets))
		{
			case "BetsBasket": //Si c'est un concours sur du basket : on supprime le bets dans la table bets_basket
				$reqDelete = $this->_db->prepare("DELETE FROM bets_basket WHERE id= :id");
				break;
			default: //Si c'est une classe qui n'est pas "connue" : on ne fait rien
				return;
		}
		$reqDelete->bindValue(":id", $bets->id());
		$reqDelete->execute();
	}
	public function update(Bets $bets)
	{
		//On teste le type de Bets
		switch(get_class($bets))
		{
			case "BetsBasket": //Si c'est un concours sur du basket : on met à jour le bets dans la table bets_basket
				$reqUpdate = $this->_db->prepare("UPDATE bets_basket SET status= :status, user_id= :user_id, contest_id= :contest_id, scheduleEvent_id= :scheduleEvent_id, winningTeam= :winningTeam, pointsDifference= :pointsDifference, pointsTotal= :pointsTotal, overtime= :overtime, resultWinningTeam= :resultWinningTeam, resultPointsDifference= :resultPointsDifference, resultPointsTotal= :resultPointsTotal, resultOvertime= :resultOvertime WHERE id= :id");
				$reqUpdate->bindValue(":status", $bets->status(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":winningTeam", $bets->winningTeam(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":pointsDifference", $bets->pointsDifference(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":pointsTotal", $bets->pointsTotal(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":overtime", $bets->overtime(), PDO::PARAM_BOOL);
				$reqUpdate->bindValue(":resultWinningTeam", $bets->resultWinningTeam(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":resultPointsDifference", $bets->resultPointsDifference(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":resultPointsTotal", $bets->resultPointsTotal(), PDO::PARAM_INT);
				$reqUpdate->bindValue(":resultOvertime", $bets->resultOvertime(), PDO::PARAM_INT);
				break;
			default: //Si c'est une classe qui n'est pas "connue" : on ne fait rien
				return;
		}
		$reqUpdate->bindValue(":id", $bets->id(), PDO::PARAM_INT);
		$reqUpdate->bindValue(":user_id", $bets->user_id(), PDO::PARAM_INT);
		$reqUpdate->bindValue(":contest_id", $bets->contest_id(), PDO::PARAM_INT);
		$reqUpdate->bindValue(":scheduleEvent_id", $bets->scheduleEvent_id(), PDO::PARAM_INT);
		$reqUpdate->execute();
	}
	
	public function validate(Bets $bets, $status)
	{
		//On teste le type de Bets
		switch(get_class($bets))
		{
			case "BetsBasket": //Si c'est un concours sur du basket
				$sportManager = new SportManager($this->_db);
				$scheduleEventManager = new ScheduleEventManager($this->_db);
				$contestManager = new ContestManager($this->_db);
				$userManager = new UserManager($this->_db);
				$sport = $sportManager->get("basket");
				$scheduleEvent = $scheduleEventManager->get($bets->scheduleEvent_id(), $sport);
				$contest = $contestManager->get($bets->contest_id());
				$user = $userManager->get($bets->user_id());
				//Si le bet n'existe pas : on le créée avec le statut $status directement
				if($this->get($sport, null, $scheduleEvent, $contest, $user) == null)
				{
					$bets->setStatus($status);
					$this->add($bets);
				}
				//S'il existe déjà : on l'update avec statut $status
				else
				{
					$betToUpdate = $this->get($sport, null, $scheduleEvent, $contest, $user);
					//On ne peut mettre à jour un pari que si ce pari déjà existant n'est pas bloqué
					if($betToUpdate->status() != 2) 
					{
						$bets->setId($betToUpdate->id());
						$bets->setStatus($status);
						$this->update($bets);
					}
				}
				break;
			default: //Si c'est une classe qui n'est pas "connue" : on ne fait rien
				return;
		}
	}
	
	public function get(Sport $sport, $search = null, ScheduleEvent $scheduleEvent = null, Contest $contest = null, User $user = null)
	{
		//Fonction qui va chercher un bets ou une liste de bets dans la table bets appropriée. Il y a plusieurs cas possibles pour la recherche :
			//$sport : seul paramètre obligatoire. Si seul paramètre renseigné : on restitue tous les bets de la table appropriée 
			//$search : paramètre facultatif. Si paramètre renseigné : on restitue le bets de la table appropriée (obtenue via le sport)
			//$scheduleEvent: paramètre facultatif. Si paramètre renseigné : on restitue tous les bets de la table appropriée (obtenue via le sport) et correspondant à ce scheduleEvent
			//$contest: paramètre facultatif. Si paramètre renseigné : on restitue tous les bets associés au contest
			//$user: paramètre facultatif. Si paramètre renseigné : on restitue tous les bets associés au player
		if($sport != null)
		{
			//Recherche d'un bets en particulier
			if($search != null)
			{
				switch($sport->id())
				{
					case 1://C'est du basket
						$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE id= :id");
					default:
						return null;
				}
				$reqSelect->bindValue(":id", $search);
				$reqSelect->execute();
				$bets = $reqSelect->fetch(PDO::FETCH_ASSOC);
				if(is_array($bets))
				{
					switch($sport())
					{
						case 1://C'est du basket
							return new BetsBasket($bets);
						default:
							return null;
					}
				}
			}
			//Recherche d'une liste de bets : ceux liés au scheduleEvent, quel que soit le contest
			elseif($scheduleEvent != null && $contest == null)
			{
				$bets = array();
				switch($sport->id())
				{
					case 1://C'est du basket
						$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE scheduleEvent_id= :id");
						$reqSelect->bindValue(":id", $scheduleEvent->id());
						$reqSelect->execute();
						while($bet = $reqSelect->fetch(PDO::FETCH_ASSOC))
						{
							$betsL = new BetsBasket($bet);
							$bets[] = $betsL;
						}
						return $bets;
					default:
						return null;
				}
			}
			//Recherche d'une liste de bets : ceux liés au contest, quel que soit le scheduleEvent
			elseif($scheduleEvent == null && $contest != null)
			{
				$bets = array();
				if($user == null) //On veut tous les bets, quel que soit le joueur
				{
					switch($sport->id())
					{
						case 1://C'est du basket
							$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE contest_id= :id");
							$reqSelect->bindValue(":id", $contest->id());
							$reqSelect->execute();
							while($bet = $reqSelect->fetch(PDO::FETCH_ASSOC))
							{
								$betsL = new BetsBasket($bet);
								$bets[] = $betsL;
							}
							return $bets;
						default:
							return null;
					}
				}
				else //On veut tous les bets du contest pour un joueur particulier
				{
					switch($sport->id())
					{
						case 1://C'est du basket
							$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE contest_id= :id AND user_id= :user_id");
							$reqSelect->bindValue(":id", $contest->id());
							$reqSelect->bindValue(":user_id", $user->id());
							$reqSelect->execute();
							while($bet = $reqSelect->fetch(PDO::FETCH_ASSOC))
							{
								$betsL = new BetsBasket($bet);
								$bets[] = $betsL;
							}
							return $bets;
						default:
							return null;
					}
				}
			}
			//Recherche d'une liste de bets : ceux liés au contest, pour un scheduleEvent en particulier
			elseif($scheduleEvent != null && $contest != null)
			{
				$bets = array();
				if($user == null) //On veut tous les bets, quel que soit le joueur, pour le scheduleEvent et le contest spécifié
				{
					switch($sport->id())
					{
						case 1://C'est du basket
							$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE contest_id= :id AND scheduleEvent_id= :id2");
							$reqSelect->bindValue(":id", $contest->id());
							$reqSelect->bindValue(":id2", $scheduleEvent->id());
							$reqSelect->execute();
							while($bet = $reqSelect->fetch(PDO::FETCH_ASSOC))
							{
								$betsL = new BetsBasket($bet);
								$bets[] = $betsL;
							}
							return $bets;
						default:
							return null;
					}
				}
				else //On veut tous les bets du contest pour un joueur particulier et le scheduleEvent en particulier
				{
					switch($sport->id())
					{
						case 1://C'est du basket
							$reqSelect = $this->_db->prepare("SELECT * FROM bets_basket WHERE contest_id= :id AND scheduleEvent_id= :id2 AND user_id= :user_id");
							$reqSelect->bindValue(":id", $contest->id());
							$reqSelect->bindValue(":id2", $scheduleEvent->id());
							$reqSelect->bindValue(":user_id", $user->id());
							$reqSelect->execute();
							$bet = $reqSelect->fetch(PDO::FETCH_ASSOC);
							if(is_array($bet)) return new BetsBasket($bet);
							return null;
						default:
							return null;
					}
				}
			}
		}
		return null;
	}
	
	public function setResult(Sport $sport, Bets $bet, ScheduleEvent $scheduleEvent)
	{
		$rulesContestManager = new RulesContestManager($this->_db);
		$contestManager = new ContestManager($this->_db);
		$rulesContest = $rulesContestManager->get($sport, $contestManager->get($bet->contest_id()));
		switch($sport->id())
		{
			case 1:
				if($scheduleEvent->winningTeam() == $bet->winningTeam() && $rulesContest->winningTeam() == 1) $bet->setResultWinningTeam($rulesContest->pointsForWTOK()); //Si le pronostic sur l'équipe vainqueur fait partie des pronos pris en compte dans le contest ET que le pari est OK
				else $bet->setResultWinningTeam(0);
				if((($scheduleEvent->pointsDifference() >= $rulesContest->pointsDifference() && $bet->pointsDifference() == 1) || ($scheduleEvent->pointsDifference() < $rulesContest->pointsDifference() && $bet->pointsDifference() == 0)) && $bet->resultWinningTeam() > 0 && $rulesContest->pointsDifference() > 0) $bet->setResultPointsDifference($rulesContest->pointsForPDOK()); //Si le pronostic sur la différence de points fait partie des pronos pris en compte dans le contest ET que le pari est OK (= résultat du match avec une différence de points supérieure à la différence de points paramétrée dans le concours + différence de points dans le concours > 0 + pari que la différence de points paramétrée dans le concours serait dépassée + bon pronostic sur l'équipe vainqueur)
				else $bet->setResultPointsDifference(0);
				if($scheduleEvent->pointsTotal() >= $rulesContest->pointsTotal() && $rulesContest->pointsTotal() > 0 && $bet->pointsTotal() == 1) $bet->setResultPointsTotal($rulesContest->pointsForPTOK()); //Si le pronostic sur le total de points fait partie des pronos pris en compte dans le contest ET que le pari est OK (= résultat du match avec un total de points supérieur au total de points paramétré dans le concours + total de points dans le concours > 0 + pari que le nbre de points serait supérieur au total paramétré dans le concours)
				else $bet->setResultPointsTotal(0);
				if($scheduleEvent->overtime() == $bet->overtime() && $rulesContest->overtime() == 1) $bet->setResultOvertime($rulesContest->pointsForOOK()); //Si le pronostic sur la prolongation fait partie des pronos pris en compte dans le contest ET que le pari est OK
				else $bet->setResultOvertime(0);
				//Mise à jour en BDD du bet
				$this->update($bet);
				break;
			default:
				return;
		}
	}
	
}